
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "nbrcosttable.h"
#include "../common/constants.h"
#include "../topology/topology.h"
#include "../utils/concurrent.h"

//这个函数动态创建邻居代价表并使用邻居节点ID和直接链路代价初始化该表.
//邻居的节点ID和直接链路代价提取自文件topology.dat. 
nbr_cost_entry_t* nbrcosttable_create()
{
  int nct_size=topology_getNbrNum()+1;
  int my_id=topology_getMyNodeID();
  nbr_cost_entry_t* nct=(nbr_cost_entry_t*)calloc(nct_size,sizeof(nbr_cost_entry_t));

  nct[0].nodeID=my_id;
  nct[0].cost=0;

  int* nbr_arr=topology_getNbrArray();
  for(int i=1;i<nct_size;i++)
  {
    int nbr_id=nbr_arr[i-1];
    nct[i].nodeID=nbr_id;
    nct[i].cost=topology_getCost(my_id,nbr_id);
  }

  free(nbr_arr);
  return nct;
}

//这个函数删除邻居代价表.
//它释放所有用于邻居代价表的动态分配内存.
void nbrcosttable_destroy(nbr_cost_entry_t* nct)
{
  free(nct);
  return;
}

//这个函数用于获取邻居的直接链路代价.
//如果邻居节点在表中发现,就返回直接链路代价.否则返回INFINITE_COST.
unsigned int nbrcosttable_getcost(nbr_cost_entry_t* nct, int nodeID)
{
  int nct_size=topology_getNbrNum()+1;
  for(int i=0;i<nct_size;i++)
    if(nct[i].nodeID==nodeID)
      return nct[i].cost;
  return INFINITE_COST;
}

//这个函数打印邻居代价表的内容.
void nbrcosttable_print(nbr_cost_entry_t* nct)
{
  int nct_size=topology_getNbrNum()+1;
  int self_id=topology_getMyNodeID();
  concurrent_printf("**********Neighbour Cost Table**********\n");
  for(int i=0;i<nct_size;i++)
  {
    concurrent_printf("src:%d dest:%d cost:%d\n",self_id,nct[i].nodeID,nct[i].cost);
  }
  concurrent_printf("**********Neighbour Cost Table**********\n");
  return;
}
